/*
 * Content.h
 *
 *  Created on: 2012-7-26
 *      Author: yangentao@gmail.com
 */

#ifndef CONTENT_H_
#define CONTENT_H_
#include "util/String.h"

class TextChangingEvent {
public:
	virtual ~TextChangingEvent() {
	}
public:
	// Start offset of the text that is going to be replaced
	int start;
	// Text that is going to be inserted or empty string
	// if no text will be inserted
	String newText;
	// Length of text that is going to be replaced
	int replaceCharCount;
	// Length of text that is going to be inserted
	int newCharCount;
	// Number of lines that are going to be replaced
	int replaceLineCount;
	// Number of new lines that are going to be inserted
	int newLineCount;
};

class TextChangedEvent {
public:
	virtual ~TextChangedEvent() {
	}

};

class TextChangeListener {
public:
	virtual ~TextChangeListener() {
	}
public:

	virtual void textChanging(TextChangingEvent* event);

	virtual void textChanged(TextChangedEvent* event);

	virtual void textSet(TextChangedEvent* event);
};

class StyledTextContent {
public:
	virtual ~StyledTextContent() {
	}
public:

	virtual void addTextChangeListener(TextChangeListener* listener);
	/**
	 * Return the number of characters in the content.
	 * <p>
	 *
	 * @return the number of characters in the content.
	 */
	virtual int getCharCount();
	/**
	 * lineIndex从0开始, 0表示第一行. 返回的字符串去掉了换行符
	 * Return the line at the given line index without delimiters.
	 * <p>
	 *
	 * @param lineIndex index of the line to return. Does not include
	 *	delimiters of preceding lines. Index 0 is the first line of the
	 * 	content.
	 * @return the line text without delimiters
	 */
	virtual String getLine(int lineIndex);
	/**
	 * offset从0开始, 也叫索引. 行分隔符跟它前面的文本是一行
	 * Return the line index at the given character offset.
	 * <p>
	 *
	 * @param offset offset of the line to return. The first character of the
	 * 	document is at offset 0.  An offset of getLength() is valid and should
	 *	answer the number of lines.
	 * @return the line index. The first line is at index 0.  If the character
	 * 	at offset is a delimiter character, answer the line index of the line
	 * 	that is delimited.
	 * 	For example, if text = "\r\n\r\n", and delimiter = "\r\n", then:
	 * <ul>
	 * <li>getLineAtOffset(0) == 0
	 * <li>getLineAtOffset(1) == 0
	 * <li>getLineAtOffset(2) == 1
	 * <li>getLineAtOffset(3) == 1
	 * <li>getLineAtOffset(4) == 2
	 * </ul>
	 */
	virtual int getLineAtOffset(int offset);
	/**
	 * 行分隔符的数量+1
	 * Return the number of lines.  Should answer 1 when no text is specified.
	 * The  StyledText widget relies on this behavior for drawing the cursor.
	 * <p>
	 *
	 * @return the number of lines.  For example:
	 * <ul>
	 * <li>	text value ==> getLineCount
	 * <li>	null ==> 1
	 * <li>	"" ==> 1
	 * <li>	"a\n" ==> 2
	 * <li>	"\n\n" ==> 3
	 * </ul>
	 */
	virtual int getLineCount();

	/**
	 * Return the line delimiter that should be used by the StyledText
	 * widget when inserting new lines. New lines entered using key strokes
	 * and paste operations use this line delimiter.
	 * Implementors may use System.getProperty("line.separator") to return
	 * the platform line delimiter.
	 * <p>
	 *
	 * @return the line delimiter that should be used by the StyledText widget
	 *	when inserting new lines.
	 */
	virtual String getLineDelimiter();
	/**
	 * Return the character offset of the first character of the given line.
	 * <p>
	 * <b>NOTE:</b> When there is no text (i.e., no lines), getOffsetAtLine(0)
	 * is a valid call that should return 0.
	 * </p>
	 *
	 * @param lineIndex index of the line. The first line is at index 0.
	 * @return offset offset of the first character of the line. The first
	 * 	character of the document is at offset 0.  The return value should
	 * 	include line delimiters.
	 * 	For example, if text = "\r\ntest\r\n" and delimiter = "\r\n", then:
	 * <ul>
	 * <li>getOffsetAtLine(0) == 0
	 * <li>getOffsetAtLine(1) == 2
	 * <li>getOffsetAtLine(2) == 8
	 * </ul>
	 */
	virtual int getOffsetAtLine(int lineIndex);
	/**
	 * Returns a string representing the content at the given range.
	 * <p>
	 *
	 * @param start the start offset of the text to return. Offset 0 is the
	 * 	first character of the document.
	 * @param length the length of the text to return
	 * @return the text at the given range
	 */
	virtual String getTextRange(int start, int length);

	virtual void removeTextChangeListener(TextChangeListener* listener);
	/**
	 * Replace the text with "newText" starting at position "start"
	 * for a length of "replaceLength".
	 * <p>
	 * Implementors have to notify the TextChangeListeners that were added
	 * using <code>addTextChangeListener</code> before and after the content
	 * is changed. A <code>TextChangingEvent</code> has to be sent to the
	 * textChanging method before the content is changed and a
	 * <code>TextChangedEvent</code> has to be sent to the textChanged method
	 * after the content has changed.
	 * The text change that occurs after the <code>TextChangingEvent</code>
	 * has been sent has to be consistent with the data provided in the
	 * <code>TextChangingEvent</code>.
	 * This data will be cached by the widget and will be used when the
	 * <code>TextChangedEvent</code> is received.
	 * <p>
	 * The <code>TextChangingEvent</code> should be set as follows:
	 * <ul>
	 * <li>event.start = start of the replaced text
	 * <li>event.newText = text that is going to be inserted or empty String
	 *	if no text will be inserted
	 * <li>event.replaceCharCount = length of text that is going to be replaced
	 * <li>event.newCharCount = length of text that is going to be inserted
	 * <li>event.replaceLineCount = number of lines that are going to be replaced
	 * <li>event.newLineCount = number of new lines that are going to be inserted
	 * </ul>
	 * <b>NOTE:</b> newLineCount is the number of inserted lines and replaceLineCount
	 * is the number of deleted lines based on the change that occurs visually.
	 * For example:
	 * <ul>
	 * <li>(replaceText, newText) ==> (replaceLineCount, newLineCount)
	 * <li>("", "\n") ==> (0, 1)
	 * <li>("\n\n", "a") ==> (2, 0)
	 * <li>("a", "\n\n") ==> (0, 2)
	 * <li>("\n", "") ==> (1, 0)
	 * </ul>
	 * </p>
	 *
	 * @param start start offset of text to replace, none of the offsets include
	 *	delimiters of preceding lines, offset 0 is the first character of the
	 * 	document
	 * @param replaceLength length of text to replace
	 * @param text text to replace
	 * @see TextChangeListener
	 */
	virtual void replaceTextRange(int start, int replaceLength, String text);
	/**
	 * Set text to "text".
	 * Implementors have to send a <code>TextChangedEvent</code> to the
	 * textSet method of the TextChangeListeners that were added using
	 * <code>addTextChangeListener</code>.
	 * <p>
	 *
	 * @param text the new text
	 * @see TextChangeListener
	 */
	virtual void setText(String text);

};


#endif /* CONTENT_H_ */
